import uiautomator2 as u2
import time, sys, os
import json
from lxml import etree
from PIL import Image
from loguru import logger
import pytesseract
import traceback
import subprocess
from PIL import ImageOps
import aircv as ac
import pyttsx3
import random
import datetime
import sqlite3
from multiprocessing import Lock,Value,Process
import tkinter as tk
from tkinter import ttk
#华为镜像源：https://repo.huaweicloud.com/repository/pypi/simple/


class MobileDevice:
    def __init__(self, device_dr):
        self.device_dr=device_dr
        self.device_id = self.device_dr[10]         # 模拟器编号
        self.login_id = self.device_dr[0]    # 手机号
        self.login_pwd = self.device_dr[1]    # 密码
        self.name = self.device_dr[3]    # 用户名

    def Device_connect(self):
        """连接模拟器或真机"""
        try:
            logname = self.login_id+'_'+ self.device_id+ '_log.txt'
            logger.add(logname, encoding="utf-8")
            time.sleep(random.randint(1, 3))
            logger.info('准备连接设备 %s ...' % self.login_id)
            d = u2.connect(self.device_id)
            logger.info(f'连接设备 {self.device_id} ({self.login_id}) 成功!' )
            # get_device_apps(d,device_id)

            #MultiDevice(d)
        except:
            logger.exception('连接设备 %s 失败！' % device_id)


    def MultiDevice(self,d, device):  # 功能执行
        # 连接数据库
        device_id=device[10]
        db=sqlite3.connect(r"db.sqlite3")
        cursor=db.cursor()
        user_id = '13300000109'
        now_position = {'direction': '买入', 'future': '小恒指期货', 'num': 0}  # 当前持仓,num为0表示没有持仓
        """现有持仓"""
        # 策略规则
        strategy_list = [{'round': 1, 'future': '小恒指期货', 'num': 1}, {'round': 2, 'future': '小恒指期货', 'num': 2},
                        {'round': 3, 'future': '恒指期货', 'num': 1},
                        {'round': 4, 'future': '恒指期货', 'num': 2}, {'round': 5, 'future': '恒指期货', 'num': 4},
                        {'round': 6, 'future': '恒指期货', 'num': 8}]
        now_round = 1  # 设为策略第1次
        rounds_count = 1 # 总轮数，止盈就算一轮结束，从策略第一次重新开始
        direction_list = ['买入', '卖出']  # 下单方向
        direction = random.choice(direction_list)  # 随机一个方向
        is_open_market=False  # 默认将开市状态设为否
        # 设置语音提示
        engine = pyttsx3.init()
        engine.setProperty('voice', 'com.microsoft.speech.platform.voice.SynthesizerVoice')
        engine.setProperty('rate', 130)
        engine.setProperty('volume', 1)


        #print('d.info',json.dumps(d.info,ensure_ascii=False))
        # 设备信息
        device_info = d.device_info
        #print("device_info",json.dumps(device_info,ensure_ascii=False))
        sys_settings = device_info.get('sys_settings')
        if sys_settings:
            logger.critical(f"当前模拟器标题为:{sys_settings.get('title')}")
        # 直接启动APP，若wait设置为True则一直等到启动结束  (uni.UNIA13BDC2=赛期二，uni.UNI97D49FD=众期模拟)
        #d.screenshot().save('full_%s.png' % device_id)


        pid=d.app_start("uni.UNI97D49FD", wait=True)


        # 等待APP启动结束，默认20秒超时，启动后 返回pid，如果启动失败则pid为0

        #pid = d.app_wait("uni.UNI97D49FD")
        #logger.info(f'{device_id} 窗口句柄为：{pid}')
        time.sleep(random.randint(6, 10))
        d.screenshot().save('full_%s.png' % device_id)


        imsrc = ac.imread('full_%s.png' % device_id)  # 源图，全范围图
        imobj = ac.imread('denglu.png')  # 登录按钮，有就表示没登录
        pos = ac.find_template(imsrc, imobj, 0.8)
        if pos is None:
            logger.warning(f'{device[0]} 当前已经登录')
        else:
            logger.warning(f'{device[0]} 当前没有登录')
            if device[2]=='模拟':
                d.click(381, 334)  # 点击登录类型下拉列表
                time.sleep(1)
                d.click(237, 462)  # 选择模拟
            else:
                d.click(381, 334)  # 点击登录类型下拉列表
                time.sleep(1)
                d.click(281, 519)  # 选择资管训练实盘

            time.sleep(1)

            d.click(333, 408)  #点击用户名
            time.sleep(0.5)
            d.set_fastinput_ime(True)
            d.clear_text()
            d.send_keys(device[0], True)
            time.sleep(0.5)
            d.press("back")
            d.click(321, 494)  #点击密码
            time.sleep(0.5)
            d.set_fastinput_ime(True)
            d.clear_text()
            d.send_keys(device[1], True)
            time.sleep(0.5)
            d.press("back")

            time.sleep(1)

            d.click(268, 590)  # 点击登录按钮



        time.sleep(2)
        #d.screenshot().save('full_%s.png' % device_id)
        #imsrc = ac.imread('full_%s.png' % device_id)  # 源图，全范围图

        # 判断有无弹窗，有的话点击确定
        if d(resourceId="android:id/alertTitle").exists:  # 发现弹窗
            d(resourceId="android:id/button1").click()  # 关闭弹窗
            logger.info(f'{device[0]} : 点击了关闭弹窗  知道了 按钮')

        time.sleep(1)
        if d(text="确认").exists():
            logger.info(f'{device[0]} : 点击了关闭弹窗 确认 按钮')
            d(text="确认").click()


        # getUserInfo(d,device_id)
        time.sleep(1)
        if d(text="交易").exists():
            logger.info(f'{device[0]} 点击了交易 按钮')
            d(text="交易").click()




        # pytesseract_pingcang(d,device_id)
        # setZhiYing(d, device_id, 18400, 18480)

        time.sleep(0.5)
        d.click(276, 800)  # 点击一下空白区域，清除底色

        if d(text="持仓").exists():
            logger.info(f'{device[0]} 点击了持仓 按钮')
            d(text="持仓").click()



        time.sleep(1)
        '''
        cursor.execute(
            "INSERT INTO hsiplus(device_id, user_id, trade_date, rounds_count, round,future,direction,quantity,phase,addtime) VALUES (?, ?, ?, ?, ?,?, ?, ?, ?, ?)",
            (device_id, user_id, time.strftime("%Y-%m-%d", time.localtime()), rounds_count,
            now_round,
            now_position["future"], now_position["direction"], now_position["num"], '止盈',
            time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
        db.commit()
        logger.info('已插入数据库！')
        '''
        cjjj=0
        # 识别是否有持仓
        if d(text="持仓").exists():
            logger.info(f'{device[0]} 点击了持仓 按钮')
            d(text="持仓").click()
            d.screenshot().save('full_%s.png' % device_id)
            #1 可能会出现全黑的截图，这个需要判断下截图大小，如果太小的话就说明有问题，需要重启下模拟器
            #2 页面数据也可能出现不刷新的情况，需要切换下页面尝试
            imsrc = ac.imread('full_%s.png' % device_id)  # 源图，全范围图
            imobj = ac.imread('pingcang_ico.png')  # 平仓图标，有就表示有持仓
            pos = ac.find_template(imsrc, imobj, 0.8)
            if pos is None:
                now_position = {'direction': '买入', 'future': '小恒指期货', 'num': 0}
                logger.warning(f'{device_id} 当前没有持仓，判断最后一手交易')
                time.sleep(1)
                now_round=pytesseract_lastorder(d,device)
                logger.warning(f'{device[0]}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  当前从第{rounds_count}轮,第{now_round}次开始')
                time.sleep(1)
            else:
                rounds_count,now_round,cjjj=pytesseract_noworder(d,device,cursor)
                time.sleep(1)
        else:
            logger.error(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  未能打开持仓界面，操作失败，请检查')


        starttime=datetime.datetime.strptime(str(datetime.datetime.now().date())+' 16:15:00', "%Y-%m-%d %H:%M:%S")
        endtime=datetime.datetime.strptime(str(datetime.datetime.now().date())+' 17:15:00', "%Y-%m-%d %H:%M:%S")
        starttime1=datetime.datetime.strptime(str(datetime.datetime.now().date())+' 02:40:00', "%Y-%m-%d %H:%M:%S")
        endtime1=datetime.datetime.strptime(str(datetime.datetime.now().date())+' 09:15:00', "%Y-%m-%d %H:%M:%S")
        starttime2=datetime.datetime.strptime(str(datetime.datetime.now().date())+' 12:00:00', "%Y-%m-%d %H:%M:%S")
        endtime2=datetime.datetime.strptime(str(datetime.datetime.now().date())+' 13:00:00', "%Y-%m-%d %H:%M:%S")
        while True:
            try:

                if starttime<=datetime.datetime.now() and datetime.datetime.now()<=endtime or starttime1<=datetime.datetime.now() and datetime.datetime.now()<=endtime1 or starttime2<=datetime.datetime.now() and datetime.datetime.now()<=endtime2:
                    is_open_market=False # 休市期间
                    print(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  当前已休市，开市后继续...[09:15-12:00,13:00-16:30,17:15-03:00]')
                else:
                    is_open_market=True # 开市

                #print(starttime,endtime,datetime.datetime.now())
                #print(f'num:{now_position["num"]}')

                try:
                    if is_open_market:  # 是开市时间段，则执行数据获取
                        now_second=datetime.datetime.now().second
                        #if now_second % 10 == 0:
                        new = pytesseract_new(d, device_id)
                        fdyk = pytesseract_fdyk(d, device_id)
                        pcyk = pytesseract_pcyk(d,device_id)
                        zje = pytesseract_total_amount(d, device_id)
                        sxf=pytesseract_commission_amount(d, device_id)
                        print(
                            f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  指数：{new}  成交均价：{cjjj}  账户金额：{zje}  浮动盈亏：{fdyk}  平仓盈亏:{pcyk}  手续费:{sxf}  当前第{rounds_count}轮，第{now_round}次')
                        #db=sqlite3.connect(r"E:\Work\ID088\his_autotrade\python_adb\db.sqlite3")
                        #cursor=db.cursor()
                        cursor.execute("update user set device_status='在线',user_floating=?,user_now_amount=?,edittime=?,rounds_count=?,round=?,user_total_amount=?,user_commission=?,user_price_index=? where user_login_id=?",(fdyk,pcyk,time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()),rounds_count,now_round,zje,sxf,cjjj,device[0]))
                        db.commit()

                        now_minute = datetime.datetime.now().minute
                        if now_minute % 10 == 0 and now_second==1:
                            d(text="K线").click()
                            time.sleep(3)
                            d(text="交易").click()



                except:
                    logger.exception('数据获取失败')

                # 监控弹窗
                if d(resourceId="android:id/alertTitle").exists:  # 发现弹窗标题
                    try:
                        msgbox = d(resourceId="android:id/alertTitle").get_text()
                    except:
                        msgbox = '弹窗标题数据获取发生错误！'
                    logger.warning(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}   发现弹窗 标题：{msgbox} ' )
                    # 发现弹窗： [止损止盈] -- 2024/5/6 16:07:09
                    #  文字识别不够准确，会有各种意外识别的错误文字情况，都会导致执行中断，最好还是做成图片识别，这个会相对稳定一些
                    if '[止损止盈]' in msgbox:  # 表示是止盈止损的触发弹窗
                        try:
                            uiObjectBox = [36, 364, 497, 524]
                            d.screenshot().crop(uiObjectBox).save('msg_%s.png' % device_id)
                            img = Image.open('msg_%s.png' % device_id)
                            #imsrc = ac.imread(img)  # 源图，全范围图
                            content = pytesseract.image_to_string(img, lang='chi_sim')  # 识别中文
                            #content = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox), lang='chi_sim')  # 识别中文
                            content = content.replace('\n', '')  # 去掉换行符
                            logger.warning(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} :   弹窗内容 ：{content}')
                            if '触发止盈' in content or '触发止公' in content or '触发止到' in content:  # 触发的是止盈  # 这个地方文字识别不准，可能会
                                msg = f'合约 {now_position["future"]} {now_position["direction"]} {now_position["num"]}手 触发止盈，当前为 第{rounds_count}轮 第{now_round}次 执行'
                                logger.critical(msg)
                                cursor.execute(
                                    "INSERT INTO hsiplus(device_id, user_id, trade_date, rounds_count, round,future,direction,quantity,phase,addtime,total_amount,now_amount,commission_amount) VALUES (?, ?, ?, ?, ?,?, ?, ?, ?, ?,?,?,?)",
                                    (device_id, device[0], time.strftime("%Y-%m-%d", time.localtime()), rounds_count,
                                    now_round,
                                    now_position["future"], now_position["direction"], now_position["num"], '止盈',
                                    time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),zje,pcyk,sxf))
                                db.commit()
                                #engine.say(msg)
                                #engine.runAndWait()
                                time.sleep(2)
                                now_round = 1  # 赢了需要从第一轮开始
                                rounds_count = rounds_count+1  # 止盈后就进行下一轮
                                now_position['num'] = 0

                                d(resourceId="android:id/button1").click()  # 关闭弹窗
                                logger.info(f'{device[0]} : 点击了关闭弹窗  知道了 按钮')
                                # 关闭弹窗后还会有个交易提示的弹窗，也需要关闭
                                time.sleep(1)
                                d(text="确认").click()
                                logger.info(f'{device[0]} : 点击了关闭弹窗 确认 按钮')


                            if '触发止损' in content:  # 触发的是止损
                                msg = f'合约 {now_position["future"]} {now_position["direction"]} {now_position["num"]}手 触发止损，当前为 第{rounds_count}轮 第{now_round}次 执行'
                                logger.critical(msg)
                                cursor.execute(
                                    "INSERT INTO hsiplus(device_id, user_id, trade_date, rounds_count, round,future,direction,quantity,phase,addtime,total_amount,now_amount,commission_amount) VALUES (?, ?, ?, ?, ?,?, ?, ?, ?, ?,?,?,?)",
                                    (device_id, device[0], time.strftime("%Y-%m-%d", time.localtime()), rounds_count,
                                    now_round,
                                    now_position["future"], now_position["direction"], now_position["num"], '止损',
                                    time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),zje,pcyk,sxf))
                                db.commit()
                                time.sleep(2)
                                #engine.say(msg)
                                #engine.runAndWait()
                                if now_round == 6:  # 表示已经是第6次
                                    msg='已经为策略第6次执行止损，账号停止交易，需上报公司接管！'
                                    logger.warning(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 当前合约已被止损，策略已执行到第{rounds_count}轮，第{now_round}次，当前程序退出')
                                    #engine.say(msg)
                                    #engine.runAndWait()
                                    # 停止APP
                                    d(resourceId="android:id/button1").click()  # 关闭弹窗
                                    logger.info(f'{device[0]} : 点击了关闭弹窗  知道了 按钮')
                                    # 关闭弹窗后还会有个交易提示的弹窗，也需要关闭
                                    time.sleep(1)
                                    d(text="确认").click()
                                    logger.info(f'{device[0]} : 点击了关闭弹窗 确认 按钮')
                                    d.app_stop("uni.UNI97D49FD")
                                    d.press("home")
                                    return

                                now_round = now_round + 1
                                now_position['num'] = 0

                                d(resourceId="android:id/button1").click()  # 关闭弹窗
                                logger.info(f'{device[0]} : 点击了关闭弹窗  知道了 按钮')
                                # 关闭弹窗后还会有个交易提示的弹窗，也需要关闭
                                time.sleep(1)
                                d(text="确认").click()
                                logger.info(f'{device[0]} : 点击了关闭弹窗 确认 按钮')

                        except:
                            logger.exception(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  执行 止盈止损  发生错误！')

                    if '风控警告' in msgbox:
                        msg=pytesseract_ok(d, device_id)
                        if '定时强平' in msg or '定时强了' in msg:   # 还是文字识别不准确
                            msg = f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  当前合约已被定时强平,策略已执行到第{rounds_count}轮，第{now_round}次，当前程序退出'
                            logger.critical(msg)
                            cursor.execute(
                                    "INSERT INTO hsiplus(device_id, user_id, trade_date, rounds_count, round,future,direction,quantity,phase,addtime,total_amount,now_amount,commission_amount) VALUES (?, ?, ?, ?, ?,?, ?, ?, ?, ?,?,?,?)",
                                    (device_id, device[0], time.strftime("%Y-%m-%d", time.localtime()), rounds_count,
                                    now_round,
                                    now_position["future"], now_position["direction"], now_position["num"], '定时强平',
                                    time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),zje,pcyk,sxf))
                            db.commit()

                            #engine.say(msg)
                            #engine.runAndWait()
                            # 停止APP
                            d.app_stop("uni.UNI97D49FD")
                            d.press("home")
                            return
                        try:
                            d(resourceId="android:id/button1").click()  # 关闭弹窗
                            d(text="确认").click()
                            time.sleep(1)
                        except:
                            logger.exception(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  点击风控相关按钮失败。')
                            now_position['num'] = 99


                    # 以上都不是，则直接关闭弹窗
                    try:
                        if d(resourceId="android:id/button1").exists():
                            d(resourceId="android:id/button1").click()  # 关闭弹窗
                            logger.warning(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  【其他情况】 点击了 button1 按钮！' )
                        if d(text="确认").exists():
                            d(text="确认").click()
                            logger.warning(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  【其他情况】 点击了确认按钮！' )

                    except:
                        logger.exception(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  【其他情况】 点击弹窗的相关按钮失败！')
                        now_position['num'] = 99

                time.sleep(2)

                # 判断是否出现没有弹窗的交易确认提示,这个作为强平判断，只在休市的时间执行
                if d(text="确认").exists():
                    msg=pytesseract_ok(d, device_id)
                    if '交易提示' in msg and '已成交' in msg:
                        # 是交易成交的提示，这个地方出现的只能是强平的提示
                        if is_open_market is False:
                            #并且是休市时间出现的，只能是强平提示
                            msg = f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  当前合约已被定时强平,策略已执行到第{rounds_count}轮，第{now_round}次，当前程序已退出。'
                            logger.critical(msg)
                            cursor.execute(
                                    "INSERT INTO hsiplus(device_id, user_id, trade_date, rounds_count, round,future,direction,quantity,phase,addtime,total_amount,now_amount,commission_amount) VALUES (?, ?, ?, ?, ?,?, ?, ?, ?, ?,?,?,?)",
                                    (device_id, device[0], time.strftime("%Y-%m-%d", time.localtime()), rounds_count,
                                    now_round,
                                    now_position["future"], now_position["direction"], now_position["num"], '定时强平',
                                    time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),zje,pcyk,sxf))
                            db.commit()
                            now_position["num"]=99  #强平的将num设为99，还执行当前次数
                            #engine.say(msg)
                            #engine.runAndWait()
                            d(text="确认").click()
                            # 停止APP
                            d.app_stop("uni.UNI97D49FD")
                            d.press("home")
                            return
                        else:
                            # 正常交易，可能是手动平仓，需要根据平仓盈亏金额增加还是减少来判断是止盈还是止损
                            logger.warning(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 发现计划外的交易信息提示：{msg}')


                            # 停止APP
                            #d.app_stop("uni.UNI97D49FD")
                            #d.press("home")
                            #return

                    else:
                        # 不是交易提示，则继续执行
                        logger.warning(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  发现计划外的交易信息提示：{msg}')
                        d(text="确认").click()
                        time.sleep(1)

                # 判断下单,首先识别是否有持仓
                #print(f"{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  now_position-num={now_position['num']}  is_open_market={is_open_market}")
                if d(text="持仓").exists():
                    d(text="持仓").click()
                    d.screenshot().save('full_%s.png' % device_id)
                    #1 可能会出现全黑的截图，这个需要判断下截图大小，如果太小的话就说明有问题，需要重启下模拟器
                    #2 页面数据也可能出现不刷新的情况，需要切换下页面尝试
                    imsrc = ac.imread('full_%s.png' % device_id)  # 源图，全范围图
                    imobj = ac.imread('pingcang_ico.png')  # 平仓图标，有就表示有持仓
                    pos = ac.find_template(imsrc, imobj, 0.8)
                    if (pos is None) and is_open_market and now_position['num']==0:
                        #没有持仓的话，先看看最后一条数是否是定时强平的，如果是，则按强平时的策略继续
                        cursor.execute("SELECT * FROM hsiplus where user_id=? and trade_date=? ORDER BY id DESC limit 1;",(device[0],time.strftime("%Y-%m-%d", time.localtime())))
                        row = cursor.fetchone()
                        if row is not None:
                            if '定时强平' == row[9]:
                                # 是定时强平的的记录，则还继续按强平时的策略执行
                                logger.info(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  强平策略为 第{row[4]}轮，第{row[5]}次，{row[6]} {row[7]} {row[8]} 手 {row[9]}')
                                logger.info(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  上次为强平策略，继续按强平时的策略执行。')
                                now_position={'direction': row[7], 'future': row[6], 'num': row[8]}
                                now_round=row[5]

                                # 如果是凌晨2点半的定时强平，需要重设当前轮次
                                addtime=datetime.datetime.strptime(row[13], '%Y-%m-%d %H:%M:%S')
                                if 2 == addtime.hour and addtime.minute>=30:
                                    rounds_count=1  # 凌晨强平的轮次重新开始
                                else:
                                    rounds_count=row[4]  # 不是凌晨2点半的强平，则继续按上次的轮次执行
                            else:
                                # 不是定时强平的
                                if rounds_count == 1:
                                    logger.info(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 当日最后记录为 {row[4]}轮，第{row[5]}次，{row[6]} {row[7]} {row[8]} 手 {row[9]}')
                                    rounds_count=row[4]  # 这个地方逻辑有点问题，判断数据库些不太准
                                    logger.info(f'{device[0]}  {device_id}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 当前轮次为第 {rounds_count}轮，第{now_round}次')


                        else:# 没有当天的交易记录，就从第一轮次开始
                            rounds_count=1
                            now_round=1


                        direction = random.choice(direction_list)  # 随机一个方向
                        strategy = strategy_list[now_round - 1]  # 获取当前轮次策略
                        cjjj=pytesseract_PlaceOrder(d, device_id, direction, strategy['future'], strategy['num'])
                        if cjjj>0:
                            now_position = {'direction': direction, 'future': strategy['future'], 'num': strategy['num']}  #重设当前持仓
                            msg = f"{device[0]}  {device_id}  {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 合约,{strategy['future']}{direction}{strategy['num']}手,已下单成功，当前为第{rounds_count}轮第{now_round}次。"
                            logger.critical(msg)
                            #engine.say(msg)
                            #engine.runAndWait()
                        else:
                            logger.error('下单失败！稍候再试')
                            now_position['num'] = 0  # 执行失败，则num设为0，下次继续执行

                time.sleep(2)


            except:
                logger.exception('设备 %s    %s 执行发生错误！' % (device_id,device[0]))
                time.sleep(random.randint(5,15))

            # d(text="成交").click()
            # time.sleep(1)
            # d(text="买入").click()








def select_hkex_type(d, future='小恒指期货'):
    """type: 恒指期货 or 小恒指期货
    """
    d.click(250, 217)
    if future == '恒指期货':
        time.sleep(1)
        d.click(149, 323)
        time.sleep(0.5)
    if future == '小恒指期货':
        time.sleep(1)
        d.click(150, 360)
        time.sleep(0.5)





def getUserInfo(d, device_id):
    """获取当前登录客户信息"""
    d(text="我的").click()
    time.sleep(1)
    d.drag(324, 718, 330, 460, 0.1)
    time.sleep(0.5)
    d.click(250, 850)
    time.sleep(3)

    uiObjectBox = [353, 251, 533, 289]  # 设置中心-手机号
    sj = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox), lang='chi_sim')  # 识别中文
    sj = sj.replace('\n', '')  # 去掉换行符
    uiObjectBox = [396, 332, 534, 369]  # 设置中心-昵称
    name = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox), lang='chi_sim')  # 识别中文
    name = name.replace('\n', '')  # 去掉换行符
    logger.info(f"当前登录用户：{name}，手机:{sj}")
    d.click(38, 71)  # 点击返回
    time.sleep(1)
    d.click(375, 915)  # 点击返交易


def setZhiYing(d, device_id, ying=0, sun=0):
    """
    设置止盈止损
    ying：止盈  -1 默认设置
    sun: 止损
    """
    time.sleep(0.5)
    d.click(276, 800)  # 点击一下空白区域，清除底色
    time.sleep(0.5)
    d(text="持仓").click()
    # 识别是否有持仓
    d.screenshot().save('full_%s.png' % device_id)
    imsrc = ac.imread('full_%s.png' % device_id)  # 源图，全范围图
    imobj = ac.imread('pingcang_ico.png')  # 平仓图标，有就表示有持仓
    pos = ac.find_template(imsrc, imobj)
    if pos is None:
        logger.error(f'{device_id} 当前没有持仓，无法设置止盈止损。')
        return None
    # x, y = pos['result']
    # d.click(x, y)
    # 执行3次滑动，回归初始位置
    d.drag(135, 746, 408, 748, 0.05)
    d.drag(135, 746, 408, 748, 0.05)
    d.drag(135, 746, 408, 748, 0.05)

    # 执行两次滑动，显示查看按钮
    d.drag(474, 732, 241, 732, 0.05)
    d.drag(474, 732, 241, 732, 0.05)
    '''
    # 查找“查看”按钮
    imobj = ac.imread('chakan.png')  # 查看图标
    pos = ac.find_template(imsrc, imobj)
    if pos is None:
        logger.error(f'{device_id} 当前没有持仓，无法设置止盈止损。')
        return None
    '''
    d.click(506, 604)  # 点击查看按钮
    time.sleep(1)
    logger.info('打开了添加止盈止损页面')
    if d(text="编辑").exists():
        logger.warning('存在止盈止损设置，进行编辑')
        d(text="编辑").click()
        time.sleep(1)
        d.xpath(
            '//*[@text="pages/transaction/dataList[13]"]/android.view.View[5]/android.view.View[1]/android.view.View[3]/android.view.View[2]').set_text(
            str(sun))
        d.xpath(
            '//*[@text="pages/transaction/dataList[13]"]/android.view.View[5]/android.view.View[1]/android.view.View[4]/android.view.View[2]').set_text(
            str(ying))
        time.sleep(2)
        d.click(281, 510)
    else:
        logger.warning('进行止盈止损添加')
        d(text="添加").click()  # 打开添加弹窗
        if ying == -1 or sun == -1:
            time.sleep(1)
            d.click(281, 510)
            logger.info('按默认值添加')
            time.sleep(1)
        else:
            d.xpath(
                '//*[@text="pages/transaction/dataList[13]"]/android.view.View[5]/android.view.View[1]/android.view.View[3]/android.view.View[2]').set_text(
                str(sun))
            d.xpath(
                '//*[@text="pages/transaction/dataList[13]"]/android.view.View[5]/android.view.View[1]/android.view.View[4]/android.view.View[2]').set_text(
                str(ying))
    
    # 截图识别成交均价
    uiObjectBox = [99, 152, 197, 180]  # 止盈止损添加窗口成交均价
    tesseract_config = r'--oem 3 --psm 6 outputbase'  # 只识别数字、小数点和-号
    d.screenshot().crop(uiObjectBox).save('cjjj_%s.png' % device_id)
    cjjj = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox), config=tesseract_config)  # 解析图片
    cjjj = cjjj.replace('\n', '')  # 去掉换行符
    time.sleep(1)
    d.click(33, 67)
    time.sleep(2)
    d.drag(74, 757, 501, 748, 0.05)
    time.sleep(0.5)
    d.click(245, 730)
    time.sleep(0.5)

    return float(cjjj)



def setNumber(d, device_id, num):
    """设置手数"""
    try:
        # d.xpath('//*[@text="pages/transaction/transaction[2]"]/android.view.View[10]/android.view.View[3]/android.view.View[1]').set_text(str(num))  # 设置手数

        uiObjectBox = [141, 266, 231, 302]  # 手数位置
        tesseract_config = r'--oem 3 --psm 6 outputbase'  # 只识别数字、小数点和-号
        d.screenshot().crop(uiObjectBox).save('shoushu_%s.png' % device_id)
        shoushu = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox), config=tesseract_config)  # 解析图片
        shoushu = shoushu.replace('\n', '')  # 去掉换行符
        shoushu = int(shoushu)
        if shoushu < num:
            print(f'当前手数{shoushu}小于要操作手数{num},准备点击')
            for i in range(num - shoushu):
                d.click(249, 286)
                time.sleep(0.3)
        if shoushu > num:
            print(f'当前手数{shoushu}大于要操作手数{num},准备点击')
            for i in range(shoushu - num):
                d.click(122, 286)
                time.sleep(0.3)


    except:
        logger.exception('设置手数失败！！')
        time.sleep(0.3)


def pytesseract_PlaceOrder(d, device_id, direction='买入', future='小恒指期货', num=1):
    """
    下单
    direction:下单方向  买入，卖出
    future_type:期货类型  恒指期货，小恒指期货
    """
    try:
        # 首先确定是否在交易页面
        '''判断是否在交易页面，根据是否有买入按钮来确定'''
        d.screenshot().save('full_%s.png' % device_id)
        imsrc = ac.imread('full_%s.png' % device_id)  # 源图，全范围图
        imobj = ac.imread('mairu.png')  # 目标图，局部图
        pos = ac.find_template(imsrc, imobj, 0.8)
        #print('图标查找',pos)
        if pos is None:
            logger.error(f'{device_id}  当前不在交易页面，下单失败！')
            return False

        logger.info(f'准备下单 {direction} {future} {num}手...')
        select_hkex_type(d, future)
        setNumber(d, device_id, num)

        time.sleep(2)
        if direction == '买入':
            d(text="买入").click()
        if direction == '卖出':
            d(text="卖出").click()
        time.sleep(2) # 等待2秒释放锁
        

        while True:
            time.sleep(1)
            if d(text="确认").exists:
                msg = pytesseract_ok(d, device_id)
                logger.warning(f'{msg}')
                if msg is not None:
                    if '委托提示' in msg:
                        d(text="确认").click()  # 委托成功提示
                        logger.info(f'{device_id},委托提示已提交！')
                        break
                    

        while True:
            time.sleep(1)
            if d(text="确认").exists:
                msg = pytesseract_ok(d, device_id)
                logger.warning(f'{msg}')
                if msg is not None:
                    if '已成交' in msg:
                        d(text="确认").click()  # 委托成功提示
                        logger.info(f'{device_id},{msg},委托交易已确认成交！')
                        break
                    if '该品种已限制开仓' in msg  or '委托失败' in msg:
                        logger.error('当前不允许下单！或者委托失败！')
                        d(text="确认").click()  # 关闭弹窗
                        time.sleep(random.randint(10, 30))
                        return False
                    if '尝试使用移动网络' in msg or '下单失败' in msg:
                        d(text="确认").click()  # 关闭弹窗
                        logger.error('相同ip同时下单，暂停一下,稍后再试')
                        time.sleep(random.randint(1, 10))
                        return False
                    if '单笔下单量超过最大限定值' in msg:
                        d(text="确认").click()  # 关闭弹窗
                        logger.error('此账号只允许下单一手。')
                        return False
        time.sleep(2)
        logger.info('设置止盈止损')
        cjjj=setZhiYing(d, device_id, -1, -1)
        return cjjj
    except:
        logger.exception('设备 %s 执行发生错误！' % device_id)
        return -1

def pytesseract_pingcang(d, device_id):
    """操作手动平仓"""
    d.screenshot().save('full_%s.png' % device_id)
    imsrc = ac.imread('full_%s.png' % device_id)  # 源图，全范围图
    imobj = ac.imread('pingcang_ico.png')  # 目标图，局部图
    pos = ac.find_template(imsrc, imobj)
    print(pos)
    if pos is None:
        return 0
    x, y = pos['result']
    d.click(x, y)
    while True:
        time.sleep(1)
        if d(text="确认").exists:
            time.sleep(1)
            msg = pytesseract_ok(d, device_id)
            logger.warning(f'平仓委托提示信息：{msg}')
            if msg is not None:
                if '委托提示' in msg:
                    d(text="确认").click()  # 委托成功提示
                    logger.info(f'{device_id},委托提示已提交！')
                    break

    while True:
        time.sleep(1)
        if d(text="确认").exists:
            time.sleep(1)
            msg = pytesseract_ok(d, device_id)
            logger.warning(f'{msg}')
            if msg is not None:
                if '已成交' in msg:
                    d(text="确认").click()  # 委托成功提示
                    logger.info(f'{device_id},委托交易已成交！')
                    break


def pytesseract_ok(d, device_id):
    """交易成功弹窗提示"""
    try:
        uiObjectBox = [45, 305, 492, 568]
        d.screenshot().crop(uiObjectBox).save('msg_%s.png' % device_id)
        img = Image.open('msg_%s.png' % device_id)
        # content = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox),lang='chi_sim')  # 识别中文
        custom_config = r'--oem 3 --psm 6 -l chi_sim'  # chi_sim for Simplified Chinese  # 尝试这个字库识别
        content = pytesseract.image_to_string(img, config=custom_config)  # 识别中文
        content = content.replace('\n', '')  # 去掉换行符
        logger.warning(f'{device_id} :    ：{content}')
        return content
    except:
        logger.exception('设备 %s 执行发生错误！' % device_id)
        return ''

def pytesseract_noworder(d, device,cursor):
    '''识别当前持仓信息'''
    try:
        device_id=device[10]
        strategy_list = [{'round': 1, 'future': '小恒指期货', 'num': 1}, {'round': 2, 'future': '小恒指期货', 'num': 2},
                        {'round': 3, 'future': '恒指期货', 'num': 1},
                        {'round': 4, 'future': '恒指期货', 'num': 2}, {'round': 5, 'future': '恒指期货', 'num': 4},
                        {'round': 6, 'future': '恒指期货', 'num': 8}]
        now_round=1
        rounds_count=1
        # 识别判断当前持仓的是什么
        d(text="持仓").click()
        time.sleep(1)
        # 执行3次滑动，回归初始位置
        d.drag(135, 746, 408, 748, 0.05)
        d.drag(135, 746, 408, 748, 0.05)
        d.drag(135, 746, 408, 748, 0.05)
        time.sleep(1)
        uiObjectBox = [91,583,303,625]
        d.screenshot().crop(uiObjectBox).save('chicang0_%s.png' % device[0])  #识别合约类型
        img = Image.open('chicang0_%s.png' % device[0])
        # content = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox),lang='chi_sim')  # 识别中文
        content = pytesseract.image_to_string(img, lang='chi_sim')  # 识别中文
        content = content.replace('\n', '')  # 去掉换行符
        future = content.replace(' ', '')  # 去掉空格
        direction=''
        if '卖' in future:
            direction='卖出'
        if '买' in future:
            direction='买入'
        
        if 'MHI' in future:
            future='小恒指期货'
        if 'HSI' in future:
            future='恒指期货'
        #logger.warning(f'{device_id} :   合约 ：{future}  方向：{direction}')
        
        d.drag(496, 732, 245, 732, 0.05)

        uiObjectBox = [234,583,394,625]
        d.screenshot().crop(uiObjectBox).save('chicang2_%s.png' % device[0])  #识别成交均价
        img = Image.open('chicang2_%s.png' % device[0])
        # content = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox),lang='chi_sim')  # 识别中文
        tesseract_config = r'--oem 3 --psm 6 outputbase'  # 只识别数字、小数点和-号
        content = pytesseract.image_to_string(img,config=tesseract_config)  # 识别数字
        cjjj = content.replace('\n', '')  # 去掉换行符
        cjjj=float(cjjj)
        logger.warning(f'{device[0]} :   成交均价 ：{cjjj}')
        uiObjectBox = [398,583,469,625]
        d.screenshot().crop(uiObjectBox).save('chicang3_%s.png' % device[0])  #识别持仓数量
        img = Image.open('chicang3_%s.png' % device[0])
        tesseract_config = r'--oem 3 --psm 6 outputbase'  # 只识别数字、小数点和-号
        content = pytesseract.image_to_string(img,config=tesseract_config)  # 识别数字
        ccsl = content.replace('\n', '')  # 去掉换行符
        logger.warning(f'{device[0]} :   持仓数量 ：{ccsl}')
        
        
        now_position = {'direction': direction, 'future': future, 'num': int(ccsl),'index':cjjj}  

        for item in strategy_list:
            if now_position['future']==item['future'] and now_position['num']==item['num']:
                now_round=item['round']
                
        logger.warning(f'{device[0]}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  当前已有持仓为：{now_position},第{now_round}次')    
        
        # 判断当前轮数
        cursor.execute("SELECT * FROM hsiplus where user_id=? and trade_date=? ORDER BY id DESC limit 1;",(device[0],time.strftime("%Y-%m-%d", time.localtime())))
        row = cursor.fetchone()
        if row is not None:
            logger.info(f'{device[0]}  {device[10]}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 当日最后记录为 {row[4]}轮，第{row[5]}次，{row[6]} {row[7]} {row[8]} 手 {row[9]}') 
            rounds_count=row[4]
        if now_round==1:
            rounds_count=rounds_count+1
        

        d.drag(109, 721, 335, 721, 0.05)
        d.click(223, 769)  # 点击一下空白区域，清除底色
        return rounds_count,now_round,cjjj
    except:
        logger.exception('设备 %s 执行发生错误！' % device[0])

def pytesseract_lastorder(d, device,):
    """解析最后成交的一单数据"""
    try:
        strategy_list = [{'round': 1, 'future': '小恒指期货', 'num': 1}, {'round': 2, 'future': '小恒指期货', 'num': 2},
                     {'round': 3, 'future': '恒指期货', 'num': 1},
                     {'round': 4, 'future': '恒指期货', 'num': 2}, {'round': 5, 'future': '恒指期货', 'num': 4},
                     {'round': 6, 'future': '恒指期货', 'num': 8}]
        d(text="持仓").click()
        time.sleep(1)
        d(text="成交").click()
        time.sleep(5)
        d.drag(135, 746, 408, 748, 0.05)
        d.drag(135, 746, 408, 748, 0.05)
        d.drag(135, 746, 408, 748, 0.05)
        time.sleep(1)
        uiObjectBox = [21, 585, 534, 626]
        #tesseract_config = r'--oem 3 --psm 6 outputbase digits -'  # 只识别数字、小数点和-号
        d.screenshot().crop(uiObjectBox).save('lastorder_%s.png' % device[0])
        time.sleep(0.3)
        #content = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox), config=tesseract_config)  # 解析图片
        img = Image.open('lastorder_%s.png' % device[0])
        custom_config = r'--oem 3 --psm 6 -l chi_sim+eng -c tessedit_char_whitelist=HMIS.0123456789'  # chi_sim for Simplified Chinese  # 尝试这个字库识别
        content = pytesseract.image_to_string(img, config=custom_config)  # chi_sim for Simplified Chinese 
        content = content.replace('\n', '')  # 去掉换行符
        content = content.split(' ')
        content = [x for x in content if x]  # 去掉空字符串
        logger.info(f'{device[0]} :    最新成交数据识别：{content}')
        if '没有' in content or len(content)==0:
            logger.info(f'{device[0]} :    没有最新成交数据！')
            return 1


        # 重新识别一次成交手数
        uiObjectBox = [296, 585, 405, 626]
        tesseract_config = r'--oem 3 --psm 6 outputbase digits -'  # 只识别数字、小数点和-号
        d.screenshot().crop(uiObjectBox).save('lastorder_0%s.png' % device[0])
        time.sleep(0.3)
        shoushu = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox), config=tesseract_config)  # 解析图片
        shoushu = shoushu.replace('\n', '')  # 去掉换行符
        logger.info(f'{device[0]} :    最后成交手数为：{shoushu}')

        # 然后识别平仓中的最后一手数据，如果盈利为负值，就是亏了，否则就是盈了
        d.click(462,465)
        time.sleep(5)
        #滑动
        d.drag(205,700,435,700,0.05)
        d.drag(205,700,435,700,0.05)
        time.sleep(1)
        d.drag(495,700,180,700,0.05)
        time.sleep(1)
        
        #识别平仓最后一手的盈亏
        uiObjectBox = [380, 582, 490, 626]
        d.screenshot().crop(uiObjectBox).save('lastorder_1%s.png' % device[0])
        time.sleep(0.3)
        img = Image.open('lastorder_1%s.png' % device[0])
        tesseract_config = r'--oem 3 --psm 6 outputbase digits -'  # 只识别数字、小数点和-号
        yk = pytesseract.image_to_string(img, config=tesseract_config)  # 识别数字
        yk = yk.replace('\n', '')  # 去掉换行符
        yk = yk.replace(' ', '')
        logger.info(f'{device[0]} :    最新成交盈亏为：{yk}')
        if float(yk)<0:
            logger.info(f'{device[0]} :    最新成交盈亏为负值，亏损！')
            zyzs='止损'
        else:
            logger.info(f'{device[0]} :    最新成交盈亏为正值，盈利！')
            zyzs='止盈'
        # 识别平仓最后一手的数据
        print(f'{content[0]},{content[2]}')
        if 'MHI' in content[0] :
            future='小恒指期货'
        else:
            future='恒指期货'

        #if content[2]=='买':
        #    direction='买入'
        #else:
        #    direction='卖出'
        direction=''
        last_position = {'direction': direction, 'future': future, 'num': int(shoushu),'index':0}  
        now_round=0
        for item in strategy_list:
            if last_position['future']==item['future'] and last_position['num']==item['num']:
                now_round=item['round']
                
        logger.warning(f'{device[0]}  {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}  当前最后一次平仓为：{last_position}, {zyzs} ,第{now_round}口')    
        if float(yk)<0:
            now_round=now_round+1
        else:
            logger.info(f'{device[0]} :    最新成交盈亏为正值，盈利！')
            now_round=1

        time.sleep(1)
        d(text="持仓").click()
        
        return now_round
    except:
        time.sleep(1)
        d(text="持仓").click()
        logger.exception('设备 %s 执行最后一手识别发生错误' % device[0])
        return 1
def pytesseract_pcyk(d, device_id):
    """解析平仓盈亏数字"""
    try:
        uiObjectBox = [177, 138, 365, 165]
        #tesseract_config = r'--oem 3 --psm 6 outputbase digits -'  # 只识别数字、小数点和-号
        d.screenshot().crop(uiObjectBox).save('pcyk_%s.png' % device_id)
        time.sleep(0.3)
        #content = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox), config=tesseract_config)  # 解析图片
        #img = Image.open('pcyk_%s.png' % device_id)
        content = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox), config=r'--oem 3 --psm 6 -l chi_sim')  # 识别中文
        content = content.replace('\n', '')  # 去掉换行符
        #print(f'{device_id}  :    平仓盈亏：{content}')
        content = content.split(':')  
        content = content[1]  # 去掉前缀文字
        #print(f'{device_id} :    平仓盈亏：{content}')
        return float(content)
    except:
        return 0
    
def pytesseract_total_amount(d, device_id):
    """解析权益金总金额数字"""
    try:
        uiObjectBox = [50, 105, 150, 135]
        #tesseract_config = r'--oem 3 --psm 6 outputbase digits -'  # 只识别数字、小数点和-号
        d.screenshot().crop(uiObjectBox).save('total_amount_%s.png' % device_id)
        time.sleep(0.3)
        #content = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox), config=tesseract_config)  # 解析图片
        #img = Image.open('pcyk_%s.png' % device_id)
        content = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox), config=r'--oem 3 --psm 6 -l chi_sim')  # 识别中文
        content = content.replace('\n', '')  # 去掉换行符
        #print(f'{device_id}  :    账户金额：{content}')
        return float(content)
    except:
        return 0
    
def pytesseract_commission_amount(d, device_id):
    """解析手续费总金额数字"""
    try:
        uiObjectBox = [388, 137, 535, 162]
        #tesseract_config = r'--oem 3 --psm 6 outputbase digits -'  # 只识别数字、小数点和-号
        d.screenshot().crop(uiObjectBox).save('commission_amount_%s.png' % device_id)
        time.sleep(0.3)
        #content = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox), config=tesseract_config)  # 解析图片
        #img = Image.open('pcyk_%s.png' % device_id)
        content = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox), config=r'--oem 3 --psm 6 -l chi_sim')  # 识别中文
        content = content.replace('\n', '')  # 去掉换行符
        #print(f'{device_id}  :    手续费：{content}')
        content = content.split(':')  
        content = content[1]  # 去掉前缀文字
        #print(f'{device_id} :    手续费：{content}')
        return float(content)
    except:
        return 0
    
def pytesseract_fdyk(d, device_id):
    """解析浮动盈亏数字"""
    try:
        uiObjectBox = [83, 140, 186, 159]
        # uiObjectBox = [50, 110, 155, 131]
        tesseract_config = r'--oem 3 --psm 6 outputbase digits -'  # 只识别数字、小数点和-号
        d.screenshot().crop(uiObjectBox).save('fdyk_%s.png' % device_id)
        time.sleep(0.3)
        content = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox), config=tesseract_config)  # 解析图片
        content = content.replace('\n', '')  # 去掉换行符
        # print(f'{device_id} :    浮动盈亏：{content}')
        return float(content)
    except:
        return 0
    

def pytesseract_new(d, device_id):
    """解析实时指数数字"""
    try:
        '''判断是否在交易页面，根据是否有买入按钮来确定'''
        #d.screenshot().save('full_%s.png' % device_id)
        #imsrc = ac.imread('full_%s.png' % device_id)  # 源图，全范围图
        #imobj = ac.imread('mairu.png')  # 目标图，局部图
        #pos = ac.find_template(imsrc, imobj)
        #if pos is None:
        #    return 0
        # 开始截取指数图片进行识别
        uiObjectBox = [352, 184, 441, 222]  # 实时指数坐标位置
        tesseract_config = r'--oem 3 --psm 6 outputbase digits -'  # 只识别数字、小数点和-号
        # d.screenshot().crop(uiObjectBox).save('zhishu_%s.png' % device_id)
        content = pytesseract.image_to_string(d.screenshot().crop(uiObjectBox).convert('L'), config=tesseract_config)
        content = content.replace('\n', '')  # 去掉换行符
        zs= float(content)
        return zs
    except:
        return -1


def find_image(image_origin, image_template, threshold, bgremove):
    match_result = ac.find_template(image_origin, image_template, threshold, bgremove)
    return match_result


def get_device_apps(d, device_id):
    # 获取设备上所有已安装应用的列表
    installed_apps = d.app_list()
    # 打印所有应用
    for app in installed_apps:
        print(app)




# 建立监控进程
def process_check(process_list):
    logname = 'process_check_log.txt'
    logger.add(logname, encoding="utf-8")
    while 1:
        logger.info('进程监控中...')
        for p in process_list:
            if not p.is_alive():
                p.start()  # 如果进程终止，则重启进程
                time.sleep(random.randint(3,8))
                logger.warning(f'{p.name} 进程异常终止，已重启！')
        time.sleep(10)  # 每隔10秒检查一次

def update_show():
    # 更新treeview中对应行显示数据
    db1=sqlite3.connect(r"db.sqlite3")
    cursor1=db1.cursor()
    cursor1.execute("select * from user")
    users=cursor1.fetchall()
    #print(f'执行表格数据更新！')
    #print(users)
    #print(tree_rowids)
    tree.tag_configure('red_text_tag', foreground='red')
    tree.tag_configure('green_text_tag', foreground='green')
    
    for dr in users:
        for item in tree_rowids:
            #print(item['userid'],dr[0])
            if item['userid']==dr[0] and dr[11]=='在线':
                tree.set(item['rowid'],'平仓盈亏',dr[7])
                tree.set(item['rowid'],'浮动盈亏',dr[6])
                tree.set(item['rowid'],'状态',dr[11])
                tree.set(item['rowid'],'账户金额',dr[5])
                tree.set(item['rowid'],'成交指数',dr[17])
                tree.set(item['rowid'],'手续费',dr[8])
                tree.set(item['rowid'],'轮/次',f'第{dr[15]}轮，第{dr[16]}次')
                now_time=datetime.datetime.now()
                edittime=datetime.datetime.strptime(dr[14], '%Y-%m-%d %H:%M:%S')
                delta = now_time - edittime
                # 获取相差的秒数
                seconds = delta.total_seconds()
                if seconds > 60:
                    tree.set(item['rowid'],'更新时间',f'{int(seconds/60)}分前')
                else:
                    tree.set(item['rowid'],'更新时间',f'{int(seconds)}秒前')

                if dr[6]>=0:
                    tree.item(item['rowid'],tags=('red_text_tag',))
                elif dr[6]<0:
                    tree.item(item['rowid'],tags=('green_text_tag',))
                #print(f'{dr[0]}   平仓盈亏：{dr[7]}   浮动盈亏：{dr[6]}  --已更新')
                break
    db1.close()
    root.after(2000,update_show)
    


def button_stop():
    #print('点击了界面停止按钮,关闭一个进程试试')
    #print(f'当前共有开启的进程 {len(process_list)} 个')
    selected_items = tree.selection()
    for item in selected_items:
        # 获取项的所有属性
        item_attributes = tree.item(item, "values")
        print(item_attributes,item_attributes[1])  # 打印选中项的信息
    user_id=item_attributes[1]
    if item_attributes[4]=='已启动':
        for p in process_list:
            #print(f'进程名：{p.name}  进程id：{p.pid}')
            if p.name == user_id:
                p.terminate()
                tree.set(item_attributes[0],'脚本','未启动')
                process_list.remove(p)
                print(f'{p.name} 进程已终止！')

                btnStart.grid(row=2,column=5)
                btnStop.grid_forget()

    
def button_start():
    selected_items = tree.selection()
    for item in selected_items:
        # 获取项的所有属性
        item_attributes = tree.item(item, "values")
        print(item_attributes,item_attributes[1])  # 打印选中项的信息
    user_id=item_attributes[1]
    if item_attributes[4]=='未启动':
        cursor.execute("select * from user where user_login_id=?",(user_id,))
        users=cursor.fetchall()
        dr=users[0]
        p = Process(target=Device_connect, args=(dr,),name=dr[0])
        p.daemon=True  # 设为守护进程，主进程退出，子进程自动退出
        p.start()
        time.sleep(1)
        process_list.append(p)
        tree.set(item_attributes[0],'脚本','已启动')
        logger.info('进程'+dr[0]+'已启动！')

        btnStart.grid_forget()
        btnStop.grid(row=2,column=5)
    


def button_clicked(event):
    # 获取选中项的信息
    item = tree.selection()[0]
    # 获取按钮的文本
    button_text = tree.item(item, "values")[0]
    # 弹窗显示按钮文本
    print(f"Button clicked with text: {button_text}")


def on_row_click(event):
    if tree.selection():
        # 取消之前的选择,只能选中一行
        for item in tree.selection():
            tree.selection_remove(item)
        # 添加当前选中的项
        tree.selection_add(event.widget.focus())


    # 获取当前选中的项
    selected_items = tree.selection()
    for item in selected_items:
        # 获取项的所有属性
        item_attributes = tree.item(item, "values")
        print(item_attributes,item_attributes[1])  # 打印选中项的信息
    
    if item_attributes[4]=='已启动':
        btnStart.grid_forget()
        btnStop.grid(row=2,column=5)
    else:
        btnStart.grid(row=2,column=5)
        btnStop.grid_forget()
    

if __name__ == '__main__':
    engine = pyttsx3.init()
    engine.setProperty('voice', 'com.microsoft.speech.platform.voice.SynthesizerVoice')
    engine.setProperty('rate', 130)
    engine.setProperty('volume', 0.8)
    engine.say("有合约已止盈")
    engine.runAndWait()
    logger.info("开始检索在线模拟器...")
    devices = []
    db=sqlite3.connect(r"db.sqlite3")
    cursor=db.cursor()
    # 匹配之前需要先清除id，防止错误！
    cursor.execute("update user set device_index='',device_id='',device_status='',user_floating=0,user_now_amount=0,rounds_count=0,round=0,user_total_amount=0,user_commission=0,user_price_index=0")
    db.commit()
    cursor.execute("select * from user")
    users=cursor.fetchall()

    #加载页面UI
    root = tk.Tk()
    root.title("账号列表")
    tree_rowids=[]
    columns = ('行编号','账号','类型', '姓名','脚本','状态','账户金额','成交指数','浮动盈亏','平仓盈亏','手续费','轮/次','更新时间')
    tree = ttk.Treeview(root,columns=columns, show='headings')
    for col in columns:
        tree.heading(col, text=col)
        tree.column(col, width=100)
    tree.grid(row=1, column=1,columnspan=10,sticky='nsew')
    for dr in users:
        rowid=tree.insert('','end',values=('',dr[0],dr[2],dr[3],dr[10],dr[11],0,0,0,0,0,'-/-','-'))
        tree.set(rowid,'行编号',rowid )  # 将行id更新为实际获取的行id
        tree_rowids.append({'rowid':rowid,'userid':dr[0]})  # 将对应关系保存到列表中
        #print(dr[0],dr[2], dr[3],dr[10],dr[11])

    tree.bind("<ButtonRelease-1>", on_row_click)
 


    
    try:
        # 根据数据库名单匹配本地模拟器
        local_devices=[]    # 本地模拟器列表
        result = subprocess.run(['ldconsole', 'list2'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        for dr in users:
            is_exist=False # 对应模拟器是否存在
            for line in result.stdout.splitlines():
                value=line.split('\t')[0]
                dv=value.split(',')
                if dv[1] == dr[0]:  # 模拟器标题和login_id相同
                    if int(dv[2]) > 0:
                        cursor.execute("update user set device_index=?,device_status='已启动',edittime=? where user_login_id=? and user_type=?",(dv[0],time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),dr[0],dr[2]))
                        db.commit()
                        local_devices.append({'login_id':dr[0],'index':dv[0],'name':dr[3],'type':dr[2],'device_id':'','status':'已启动'})
                    else:
                        cursor.execute("update user set device_index=?,device_status='未启动',edittime=? where user_login_id=? and user_type=?",(dv[0],time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),dr[0],dr[2]))
                        db.commit()
                        local_devices.append({'login_id':dr[0],'index':dv[0],'name':dr[3],'type':dr[2],'device_id':'','status':'未启动'})
                    is_exist=True
            if not is_exist:  # 表示本地模拟器不存在
                #result_add=os.system("ldconsole copy --name "+ dr[0] +" --from 主镜像")
                local_devices.append({'login_id':dr[0],'index':'','name':dr[3],'type':dr[2],'device_id':'','status':'不存在'})  # 未知就表示未启动没有模拟器存在
    except:
        print(traceback.format_exc())

    
    
    
    # 窗口一键排序，按索引顺序排列
    result = subprocess.run(['ldconsole', 'sortWnd'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 
    time.sleep(1)      
    #for item in local_devices:
    #    print(item)

    # 获取adb实际连接设备列表
    try:
        result = subprocess.run(['adb', 'devices'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        n=0
        for line in result.stdout.splitlines():
            if  'List of devices' not in line and line!="":
                #print(line.split('\t'))
                device_id=line.split('\t')[0] # 截取设备号：emulator-5556  
                port=device_id.split('-')[1]  # 截取端口号  (端口号计算规则：5554+（index*2）)
                index=(int(port)-5554)/2
                #print(line.split('\t')[1])
                if line.split('\t')[1] == 'offline':
                    cursor.execute("update user set device_id=?,device_status='离线',edittime=? where device_index=?",(device_id,time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),index))
                    db.commit()
                    #os.system("ldconsole reboot --name "+ devices[n]['name'])
                    #time.sleep(10)
                if line.split('\t')[1] == 'device':
                    cursor.execute("update user set device_id=?,device_status='在线',edittime=? where device_index=?",(device_id,time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),index))
                    db.commit()
                    #print('执行了模拟器数据更新')
                n=n+1
    except:
        logger.error('检索模拟器失败！')

    
    cursor.execute("select * from user")
    users=cursor.fetchall()
    process_list=[]
    #print(tree_rowids)
    print('子进程开始启动....')
    for dr in users:
        if dr[11] == '在线':
            p = Process(target=Device_connect, args=(dr,),name=dr[0])
            p.daemon=True  # 设为守护进程，主进程退出，子进程自动退出
            p.start()
            time.sleep(1)
            process_list.append(p)
            logger.info('进程'+dr[0]+'已启动！')
            for item in tree_rowids:
                if dr[0] == item['userid']:  # 匹配账号
                    tree.set(item['rowid'],'脚本','已启动')
        else:
            for item in tree_rowids:
                if dr[0] == item['userid']:  # 匹配账号
                    tree.set(item['rowid'],'脚本','未启动')
    

    print('子进程启动完毕')

    btnStart = tk.Button(root, text="启动选中项脚本",
                         font=("宋体", 14),  # 设置字体和字号
                        bg="red",              # 设置背景颜色
                        fg="white",              # 设置前景颜色（文本颜色） 
                        command=button_start)
    btnStop = tk.Button(root, text="停止选中项脚本",
                         font=("宋体", 14),  # 设置字体和字号
                        bg="green",              # 设置背景颜色
                        fg="white",              # 设置前景颜色（文本颜色） 
                        command=button_stop)




    
    # 放置按钮在窗口中
    #btnStart.grid(row=2, column=5, padx=10, pady=10)
    #btnStop.grid(row=2, column=6, padx=10, pady=10)
    


    logger.info('主进程启动完毕,启动页面刷新')
    update_show()

    

    root.mainloop()
            

   
